from django.http import JsonResponse
from web.scraper.line2 import AllAiLine2
from web.models import Users, Images,FunctionId
from django import forms
from django.forms.models import model_to_dict
import json
from django.conf import settings
from django.core.files.storage import default_storage
import os
import time
from django.http import StreamingHttpResponse
ai_line2 = AllAiLine2()

# 统一返回格式
def result(code, message, data=None):
    return JsonResponse({'code': code, 'message': message, 'data': data})


# 图片表表单
class ImagesForm(forms.ModelForm):
    class Meta:
        model = Images
        fields = ['image', 'user_id']

# 上传图片
def upload_image(request):
    if request.method == 'GET':
        return result(405, '请求方法错误')
    try:
        # 获取请求头中的用户user_id
        user_id = request.headers.get('Authorization')
        if not user_id:
            return result(401, '未授权')
        # 根据user_id查询用户   
        user = Users.objects.filter(user_id=user_id).first()
        if not user:
            return result(401, '未授权')
            
        # 创建图片表
        image = ImagesForm(request.POST, request.FILES)
        if image.is_valid():
            # 获取原始文件名和扩展名
            original_file = request.FILES['image']
            file_ext = os.path.splitext(original_file.name)[1]
            
            # 生成新的文件名 (用户ID/_.扩展名)
            timestamp = int(time.time())
            new_filename = f"{user_id}/_{timestamp}{file_ext}"
            
            # 保存文件前修改文件名
            image.instance.image.name = new_filename
            
            # 保存到数据库
            image.save()
            
            image_data = model_to_dict(image.instance)
            image_data['image'] = image_data['image'].url
            return result(200, '上传成功', image_data)
        else:
            return result(400, '上传失败', json.loads(image.errors.as_json()))
    except ValueError as e:
        return result(400, '上传失败', e.args[0])
    except Exception as e:
        return result(500, '上传失败', str(e.args[0]))

# 本地上传
def local_upload(image):
    # 获取图片路径
    image_path = str(settings.BASE_DIR) + image.image.url
    # 上传图片
    response = ai_line2.upload_image.upload_image(image_path)['response']['resourceUrl']
    # 识别图片
    function_id = FunctionId.objects.filter(function_id=1).first()
    if function_id is None:
        # 创建功能id
        dialogue_id = ai_line2.create_dialogue()['id']
        function_id = FunctionId.objects.create(function_id=1, dialogue_id=dialogue_id, function_name='图片转文字')
    # 创建对话id
    dialogue_id = function_id.dialogue_id
    response = ai_line2.identify_image_content(response, dialogue_id=dialogue_id)
    # 获取识别结果
    result = response.split("#IMAGETEXTSTART")[1].split("#IMAGETEXTEND")[0]
    # 更新图片表
    image.recognized_result = result
    image.is_recognized = True
    image.save()
    return result

# 图片转文字: 采用ai识别
def img_to_textv1(request):
    if request.method == 'GET':
        return result(405, '请求方法错误')
    # 获取请求头中的用户user_id
    user_id = request.headers.get('Authorization')
    if not user_id:
        return result(401, '未授权')
    
    # 根据user_id查询用户
    user = Users.objects.filter(user_id=user_id).first()
    if not user:
        # 有参数但是没有用户,可能是伪造的,先获取他的真实IP
        # 获取请求头中的真实IP
        real_ip = request.META.get('REMOTE_ADDR')
        # 封禁IP
        print(f"封禁IP: {real_ip}")

        return result(401, '未授权')
    # 判断是本地上传还是网络上传
    image_type = request.POST.get('image_type')
    if not image_type:
        return result(400, '请选择上传方式')
    if image_type == 'local':
        # 本地上传
        image_id = request.POST.get('image_id')
        if not image_id:
            return result(400, '请上传图片')
        image = Images.objects.filter(image_id=image_id).first()
        if not image:
            return result(400, '图片不存在')
        

        # 判断图片是否已经识别过
        if image.recognized_result:
            return result(200, '该图片已识别过', image.recognized_result)
        # 判断图片中的user_id是否与当前用户一致
        if str(image.user_id.user_id) != user_id:
            return result(401, '当前图片不属于您')
 
        


        return result(200, '识别成功', local_upload(image))
    elif image_type == 'network':
        # 网络上传
        return result(400, '网络上传暂未开放')
    else:
        return result(400, '上传方式错误')


# 流式输出
def stream_response(response):
    for line in response.iter_lines():
        if line:
            try:
                text = line.decode('utf-8')
                if text.startswith('data: '):
                    text = text.replace('data: ', '')
                    if text == "[DONE]":
                        yield "data: [DONE]\n\n"
                        break
                    text = json.loads(text)
                    
                    # print(text['msg'], end="", flush=True)
                    yield f"data: {text['msg']}\n\n"
            except json.JSONDecodeError as e:
                pass
            except KeyError as e:
                pass

# 图片转文字: 采用ai识别,流式输出
def img_to_textv2(request):
    # if request.method == 'GET':
    #     return result(405, '请求方法错误')
    image_id = request.GET.get('image_id')
    if not image_id:
        return result(400, '请上传图片')
    image = Images.objects.filter(image_id=image_id).first()
    if not image:
        return result(400, '图片不存在')
    # 获取图片路径
    image_path = str(settings.BASE_DIR) + image.image.url
    # 上传图片
    response = ai_line2.upload_image.upload_image(image_path)['response']['resourceUrl']
    # 识别图片
    function_id = FunctionId.objects.filter(function_id=1).first()
    if function_id is None:
        # 创建功能id
        dialogue_id = ai_line2.create_dialogue()['id']
        function_id = FunctionId.objects.create(function_id=1, dialogue_id=dialogue_id, function_name='图片转文字')
    # 创建对话id
    dialogue_id = function_id.dialogue_id
    response = ai_line2.identify_image_content(response, dialogue_id=dialogue_id, stream=True, user_message="请精确提取图片中的文字内容，以纯文本形式呈现，不要使用 Markdown 语法、代码\正在解析这个词或任何其他干扰性内容。 ")
    response = StreamingHttpResponse(stream_response(response), content_type="text/event-stream")
    response.headers['Cache-Control'] = 'no-cache'
    return response
    


